home *** CD-ROM | disk | FTP | other *** search
/ IRIX 5.3 for Indy R4400 / IRIX 5.3 for Indy R4400 175MHz.img / dist / eoe2.idb / usr / lib / acct / runacct.z / runacct
Text File  |  1995-02-28  |  14KB  |  456 lines

  1. #!/sbin/sh
  2. #    Copyright (c) 1993 UNIX System Laboratories, Inc.
  3. #      All Rights Reserved
  4.  
  5. #    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF
  6. #    UNIX System Laboratories, Inc.       
  7. #    The copyright notice above does not evidence any
  8. #    actual or intended publication of such source code.
  9.  
  10. #    copyright    "%c%"
  11.  
  12. #!/sbin/sh
  13.  
  14.  
  15. #ident    "@(#)acct:common/cmd/acct/runacct.sh    1.9.1.6"
  16. #ident "$Header: /proj/irix5.3/isms/irix/cmd/acct/RCS/runacct.sh,v 1.5 1993/11/05 04:28:06 jwag Exp $"
  17. #       "nitely accounting shell, should be run from cron (adm) at 4am"
  18. #    "does process, connect, disk, and fee accounting"
  19. #    "prepares command summaries"
  20. #    "shell is restartable and provides reasonable diagnostics"
  21. _adm=/var/adm
  22. _nite=/var/adm/acct/nite
  23. _sum=/var/adm/acct/sum
  24. _wtmp=/var/adm/wtmp
  25. export PATH
  26. PATH=/usr/lib/acct:/bin:/usr/bin:/etc
  27. _statefile=${_nite}/statefile
  28. _active=${_nite}/active
  29. _lastdate=${_nite}/lastdate
  30. _errormsg="\n\n************ ACCT ERRORS : see  ${_active}${_date}********\n\n"
  31. _MIN_BLKS=500
  32.  
  33. cd ${_adm}
  34. #        "make sure that 2 crons weren't started, or leftover problems"
  35. date  > ${_nite}/lock1
  36. chmod 400 ${_nite}/lock1
  37. ln ${_nite}/lock1 ${_nite}/lock
  38. if test $? -ne 0; then
  39.     _lnkerr="\n\n*********** 2 CRONS or ACCT PROBLEMS***********\n\n\n"
  40.     (date ; echo "$_lnkerr" ) >/dev/console
  41.     echo "$_lnkerr" | mail adm root
  42.     echo "ERROR: locks found, run aborted" >> ${_active}
  43.     rm -f ${_nite}/lock*
  44.     exit 1
  45. fi
  46.  
  47. # Check to see if there is enough space in /var/adm to do nitely accounting
  48. #_blocks=`df /usr | sed "s/.*:  *\([0-9][0-9]*\) blocks.*/\1/"`
  49. #
  50. # Also check /var/adm rather than /usr: could be a separate filesystem!
  51.  
  52. _blocks=`df /var/adm |awk '/avail/ {next} /.*/ {print $5}'`
  53. if [ "$_blocks" -le $_MIN_BLKS ];then
  54.     echo "runacct: Insufficient space in /var/adm ($_blocks blks); \c"
  55.     echo "Terminating procedure"
  56.     ( echo "runacct: Insufficient space in /var/adm ($_blocks blks); \c"
  57.     echo "Terminating procedure" ) | \
  58.          tee /dev/console ${_active} | mail root adm
  59.     rm -f ${_nite}/lock*
  60.     exit 1
  61. fi
  62.  
  63.  
  64. case $# in
  65. 0)
  66. #    "as called by the cron each day"
  67.     _date="`date +%m%d`"
  68.     if test ! -r ${_lastdate} ; then
  69.         echo "0000" > ${_lastdate}
  70.     fi
  71.     if test "${_date}" = "`cat ${_lastdate}`"; then
  72.         (date; echo "${_errormsg}") > /dev/console
  73.         echo "${_errormsg}" | mail root adm
  74.         echo "ERROR: acctg already run for `date`: check ${_lastdate}" >> ${_active}
  75.         rm -f ${_nite}/lock*
  76.         mv ${_active} ${_active}${_date}
  77.         exit 1
  78.     fi
  79.     echo ${_date} > ${_lastdate}
  80.     echo "SETUP" > ${_statefile}
  81.     nulladm ${_active}
  82.     echo ${_date} > ${_active}    # debuging
  83.     echo "\n\n\n\n\n**********  SYSTEM ACCOUNTING STARTED `date`  **********\n\n\n\n\n" > /dev/console
  84.     echo ${_date} > ${_active}    # debuging
  85.     ;;
  86.  
  87. 1)
  88. #    "runacct MMDD  (date)  will restart at current state"
  89.     _date=$1
  90.     echo "restarting acctg for ${_date} at `cat ${_statefile}`" >> ${_active}
  91.     echo "\n\n\n\n\n********** SYSTEM ACCOUNTING RESTARTED `date` **********\n\n\n\n\n" > /dev/console
  92.     ;;
  93.  
  94. 2)
  95. #    "runacct MMDD STATE  restart at specified state"
  96.     _date=$1
  97.     echo "restarting acctg for ${_date} at $2" >> ${_active}
  98.     echo "previous state was `cat ${_statefile}`" >> ${_active}
  99.     echo "$2" > ${_statefile}
  100.     echo "\n\n\n\n\n********** SYSTEM ACCOUNTING RESTARTED `date` **********\n\n\n\n\n" > /dev/console
  101.     ;;
  102. *)
  103.     (date; echo "${_errormsg}") > /dev/console
  104.     echo "${_errormsg}" | mail root adm
  105.     echo "ERROR: runacct called with invalid arguments" > ${_active}
  106.     rm -f ${_nite}/lock*
  107.     mv ${_active} ${_active}${_date}
  108.     exit 1
  109.     ;;
  110. esac
  111.  
  112.  
  113. #    "processing is broken down into seperate, restartable states"
  114. #    "the statefile is updated at the end of each state so that the"
  115. #    "next loop through the while statement switches to the next state"
  116. while [ 1 ]
  117. do
  118. case "`cat ${_statefile}`" in
  119. SETUP)
  120.  
  121. cd ${_adm}
  122.  
  123. (date ; ls -l fee pacct* ${_wtmp}* ) >> ${_active}
  124.  
  125. #    "switch current pacct file"
  126. turnacct switch
  127. _rc=$?
  128. if test ${_rc} -ne 0; then
  129.     (date ; echo "${_errormsg}" ) > /dev/console
  130.     echo "${_errormsg}" | mail root adm
  131.     echo "ERROR: turnacct switch returned rc=${_rc}" >> ${_active}
  132.     rm -f ${_nite}/lock*
  133.     mv ${_active} ${_active}${_date}
  134.     exit 1
  135. fi
  136.  
  137. #    " give pacct files unique names for easy restart "
  138. for _i in pacct?*
  139. do
  140.     if test -r S${_i}.${_date} ; then
  141.          (date ; echo "${_errormsg}" ) > /dev/console
  142.         echo "${_errormsg}" | mail root adm
  143.         echo "ERROR: S${_i}.${_date} already exists" >> ${_active}
  144.         echo "file setups probably already run" >> ${_active}
  145.         rm -f ${_nite}/lock*
  146.         mv ${_active} ${_active}${_date}
  147.         exit 1
  148.     fi
  149.     mv ${_i} S${_i}.${_date}
  150. done
  151.  
  152.  
  153. #    "add current time on end"
  154. if test -r ${_nite}/wtmp.${_date} ; then
  155.     (date ; echo "${_errormsg}" ) > /dev/console
  156.     echo "${_errormsg}" | mail root adm
  157.     echo "ERROR: ${_nite}/wtmp.${_date} already exists: run setup manually" > ${_active}
  158.     rm -f ${_nite}/lock*
  159.     mv ${_active} ${_active}${_date}
  160.     exit 1
  161. fi
  162. closewtmp    # fudge a DEAD_PROCESS for /var/adm/wtmp
  163. cp ${_wtmp} ${_nite}/wtmp.${_date}
  164. acctwtmp "runacct" >> ${_nite}/wtmp.${_date}
  165. nulladm ${_wtmp}
  166. utmp2wtmp -t    # fudge active user from utmp to wtmp
  167.  
  168. echo "files setups complete" >> ${_active}
  169. echo "WTMPFIX" > ${_statefile}
  170. ;;
  171.  
  172. WTMPFIX)
  173. #    "verify the integrity of the wtmp file"
  174. #    "wtmpfix will automatically fix date changes"
  175. cd ${_nite}
  176. nulladm tmpwtmp wtmperror
  177. wtmpfix < wtmp.${_date} > tmpwtmp 2>wtmperror
  178. if test $? -ne 0 ; then
  179.     (date ; echo "${_errormsg}") | mail root adm
  180.     echo "${_errormsg}" > /dev/console
  181.     echo "ERROR: wtmpfix errors see ${_nite}/wtmperror${_date}" >> ${_active}
  182.     rm -f ${_nite}/lock*
  183.     mv ${_active} ${_active}${_date}
  184.     mv wtmperror wtmperror${_date}
  185.     exit 1
  186. fi
  187.  
  188. echo "wtmp processing complete" >> ${_active}
  189. echo "CONNECT" > ${_statefile}
  190. ;;
  191.  
  192.  
  193. CONNECT)
  194. #    "produce connect records"
  195. #    "the lineuse and reboots files are used by prdaily"
  196. cd ${_nite}
  197. nulladm lineuse reboots log ctacct.${_date}
  198. acctcon -l lineuse -o reboots < tmpwtmp  2> log > ctacct.${_date}
  199. _rc=$?
  200. if test -s log ; then 
  201.     fmtmsg -u console "`echo "${_errormsg}"`"
  202.     cat ${_nite}/log >> ${_active}
  203.     (date ; cat ${_nite}/log) | mail adm root
  204.     if test ${_rc} -eq 0 ; then
  205.         # if this test is true, then pnpsplit complained about
  206.         # the year and holidays not being up to date.
  207.         # This used to be a fatal error, but now it will
  208.         # continue to process the accounting.
  209.         fmtmsg -u console "     holiday file error in acctcon"
  210.     fi
  211.     if test ${_rc} -eq 4 ; then
  212.         # acctcon ran out of room to account for all users
  213.         # accounting completed for users we had room for
  214.         # nonfatal error
  215.         fmtmsg -u console "     connect accounting incomplete"
  216.     fi
  217.     if test ${_rc} -eq 2 ; then
  218.         # bad records, types or times encountered
  219.         # nonfatal error
  220.         fmtmsg -u console "     bad records encountered by acctcon"
  221.     fi
  222.     if test ${_rc} -eq 3 ; then
  223.         # could not complete connect acctg due to not enough
  224.         # room to store tty line names
  225.         # fatal error
  226.         fmtmsg -u console "Terminating procedure"
  227.         rm -f ${_nite}/lock*
  228.         mv ${_active} ${_active}${_date}
  229.         exit 3
  230.     fi
  231. fi
  232.  
  233. echo "connect acctg complete" >> ${_active}
  234. echo "PROCESS" > ${_statefile}
  235. ;;
  236.  
  237.  
  238. PROCESS)
  239. #    "correlate Spacct and ptacct files by number"
  240. #    "will not process Spacct file if corresponding ptacct exists"
  241. #    "remove the ptacct file to rurun the Spacct file"
  242. #    "if death occurs here, rerunacct should remove last ptacct file"
  243.  
  244. cd ${_nite}
  245. for _Spacct in ${_adm}/Spacct*.${_date}
  246. do
  247.     _ptacct=`basename ${_Spacct} | sed 's/Sp/pt/'`
  248.     if test -s ${_ptacct}; then
  249.         echo "WARNING: accounting already run for ${_Spacct}" \
  250.             >> ${_active}
  251.         echo "WARNING: remove ${_nite}/${_ptacct} to rerun" \
  252.             >> ${_active}
  253.     else
  254.         nulladm ${_ptacct}
  255.         acctprc < ${_Spacct} > ${_ptacct}
  256.     
  257.         echo "process acctg complete for ${_Spacct}" >> ${_active}
  258.     fi
  259. done
  260. echo "all process actg complete for ${_date}" >> ${_active}
  261. echo "MERGE" > ${_statefile}
  262. ;;
  263.  
  264.  
  265. MERGE)
  266. cd ${_nite}
  267. #    "merge ctacct and ptacct files together"
  268. acctmerg ptacct*.${_date} < ctacct.${_date} > daytacct
  269.  
  270. echo "tacct merge to create daytacct complete" >> ${_active}
  271. echo "FEES" > ${_statefile}
  272. ;;
  273.  
  274.  
  275. FEES)
  276. cd ${_nite}
  277. #    "merge in fees"
  278. if test -s ${_adm}/fee; then
  279.     cp daytacct tmpdayt
  280.     sort +0n +2 ${_adm}/fee | acctmerg -i | acctmerg tmpdayt  > daytacct
  281.     echo "merged fees" >> ${_active}
  282.     rm -f tmpdayt
  283. else
  284.     echo "no fees" >> ${_active}
  285. fi
  286. echo "DISK" > ${_statefile}
  287. ;;
  288.  
  289.  
  290. DISK)
  291. cd ${_nite}
  292. #    "the last act of any disk acct procedure should be to mv its"
  293. #    "entire output file to disktacct, where it will be picked up"
  294. if test -r disktacct; then
  295.     cp daytacct tmpdayt
  296.     acctmerg disktacct  < tmpdayt > daytacct
  297.     echo "merged disk records" >> ${_active}
  298.     rm -f tmpdayt
  299.     mv disktacct /tmp/disktacct.${_date}
  300. else
  301.     echo "no disk records" >> ${_active}
  302. fi
  303. echo "MERGETACCT" > ${_statefile}
  304. ;;
  305.  
  306. MERGETACCT)
  307. cd ${_adm}/acct
  308. #    "save each days tacct file in sum/tacct.${_date}"
  309. #    "if sum/tacct gets corrupted or lost, could recreate easily"
  310. #    "the monthly acctg procedure should remove all sum/tacct files"
  311. cp nite/daytacct sum/tacct${_date}
  312. if test ! -r sum/tacct; then
  313.     echo "WARNING: recreating ${_adm}/sum/tacct " >> ${_active}
  314.     nulladm sum/tacct
  315. fi
  316.  
  317. #    "merge in todays tacct with the summary tacct"
  318. cp sum/tacct sum/tacctprev
  319. acctmerg sum/tacctprev  < sum/tacct${_date} > sum/tacct
  320.  
  321. echo "updated sum/tacct" >> ${_active}
  322. echo "CMS" > ${_statefile}
  323. ;;
  324.  
  325.  
  326. CMS)
  327. cd ${_adm}/acct
  328. #    "do command summaries"
  329. nulladm sum/daycms
  330. if test ! -r sum/cms; then
  331.     nulladm sum/cms
  332.     echo "WARNING: recreating ${_adm}/sum/cms " >> ${_active}
  333. fi
  334. cp sum/cms sum/cmsprev
  335. acctcms ${_adm}/Spacct*.${_date}  > sum/daycms
  336. acctcms -s sum/daycms sum/cmsprev  > sum/cms
  337. acctcms -a -s sum/daycms | sed -n 1,56p  > nite/daycms
  338. acctcms -a -s sum/cms | sed -n 1,56p  > nite/cms
  339. lastlogin 
  340. echo "command summaries complete" >> ${_active}
  341. echo "USEREXIT" > ${_statefile}
  342. ;;
  343.  
  344.  
  345. USEREXIT)
  346. #    "any installation dependant accounting programs should be run here"
  347. [ -s /usr/lib/acct/runacct.local ] && /usr/lib/acct/runacct.local
  348.  
  349. echo "CLEANUP" > ${_statefile}
  350. ;;
  351.  
  352.  
  353. CLEANUP)
  354. cd ${_adm}/acct
  355. #    " finally clear files; could be done next morning if desired"
  356. nulladm ${_adm}/fee
  357. rm -f ${_adm}/Spacct*.${_date}
  358. #    "put reports onto a file"
  359. prdaily >> sum/rprt${_date};
  360. rm -f nite/lock*
  361. rm -f nite/ptacct*.${_date} nite/ctacct.${_date}
  362. mv nite/wtmp.${_date} nite/owtmp
  363. rm -f nite/wtmperror${_date} nite/active${_date} nite/tmpwtmp
  364. echo "system accounting completed at `date`" >> ${_active}
  365. mv ${_active} ${_active}${_date}
  366. echo "********** SYSTEM ACCOUNTING COMPLETED `date` **********" > /dev/console
  367. echo "COMPLETE" > ${_statefile}
  368. exit 0
  369. ;;
  370.  
  371. *)
  372.     (date;echo "${_errormsg}") > /dev/console
  373.     echo "${_errormsg}" | mail adm root
  374.     echo "ERROR: invalid state, check ${_statefile}" >> active
  375.     rm -f ${_nite}/lock*
  376.     mv ${_active} ${_active}${_date}
  377.     exit 1
  378.     ;;
  379. esac
  380. done
  381.  
  382.  
  383. #    " runacct is normally called with no arguments from the cron"
  384. #    " it checks its own locks to make sure that 2 crons or previous"
  385. #    " problems have not occured"
  386.  
  387. #    " runacct uses the statefile to record its progress"
  388. #    " each state updates the statefile upon completion"
  389. #    " then the next loop though the while picks up the new state"
  390.  
  391. #    " to restart this shell,  check the active file for diagnostics"
  392. #    " fix up any corrupted data (ie. bad pacct or wtmp files)"
  393. #    " if runacct detected the error it removes the locks"
  394. #    " remove the locks if necessary, otherwise runacct will complain"
  395. #    " the lastdate file should be removed or changed"
  396. #    " restart runacct at current state with:  runacct MMDD"
  397. #    " to override the statefile: runacct MMDD STATE"
  398.  
  399.  
  400. #    " if runacct has been executed after the latest failure"
  401. #    " ie. it ran ok today but failed yesterday"
  402. #    " the statefile will not be correct"
  403. #    " check the active files and restart properly"
  404.  
  405. #    " if runacct failed in the PROCESS state, remove the last"
  406. #    " ptacct file because it may not be complete"
  407.  
  408. #    " if shell has failed several days, do SETUP manually"
  409. #    " then rerun runacct once for each day failed"
  410. #    " could use fwtmp here to split up wtmp file correctly"
  411.  
  412. #    " normally not a good idea to restart the SETUP state"
  413. #    " should be done manually, or just cleanup first"
  414.  
  415.  
  416. #    " FILE USAGE:    all files in /var/adm/acct/nite unless specified"
  417.  
  418. #    " statefile    records progess of runacct"
  419. #    " lastdate    last day runacct ran in date +%m%d format"
  420. #    " lock lock1    controls serial use of runacct"
  421. #    " active    place for all descriptive and error messages"
  422. #    " fd2log    fd2 output for runacct ( see cron entry ) "
  423. #    " wtmp.MMDD owtmp yesterdays wtmp file"
  424. #    " tmpwtmp    yesterdays wtmp corrected by wtmpfix"
  425. #    " wtmperror    place for wtmpfix error messages"
  426. #    " lineuse    lineusage report used in prdaily"
  427. #    " reboots    reboots report used in prdaily"
  428. #    " log        place for error messages from acctcon1"
  429. #    " ctacct.MMDD    connect tacct records for MMDD"
  430. #    " ptacct.n.MMDD    process tacct records n files for MMDD"
  431. #    " daytacct    total tacct records for this days accounting"
  432. #    " disktacct    disk tacct records produced by disk shell"
  433. #    " daycms    ascii daily command summary used by prdaily"
  434. #    " cms        acsii total command summary used by prdaily"
  435.  
  436. #    " following files in /var/adm directory"
  437.  
  438. #    " fee        output from chargefee program"
  439. #    " pacct        active pacct file"
  440. #    " pacctn    switched pacct files"
  441. #    " Spacctn.MMDD    pacct files for MMDD after SETUP state"
  442. #    " wtmp        active wtmp file"
  443.  
  444. #    " following files in /var/adm/acct/sum"
  445.  
  446. #    " loginlog    output of lastlogin used in prdaily"
  447. #    " tacct        total tacct file for current fiscal"
  448. #    " tacct.MMDD    tacct file for day MMDD"
  449. #    " cms        total cms file for current fiscal"
  450. #    " rprt.MMDD    output of prdaily program"
  451. #    " wtmp.MMDD    saved copy of wtmp for MMDD"
  452. #    " pacct.MMDD    concatenated version of all pacct files for MMDD"
  453. #    " cmsprev    total cms file without latest update"
  454. #    " tacctprev    total tacct file without latest update"
  455. #    " daycms    cms files for todays usage"
  456.